using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.ArcMapUI;
using BesAsm.MasterData.Entities;
using BesAsm.Framework.Reporting;

namespace BesAsm.Emgaats.Core
{
  public delegate void ExtensionStateChangedHandler(object sender, EmgaatsExtensionArgs e);

  /// <summary>
  /// A base class for all Emgaats Extensions to inherit from. Provides functionality for handling standard ArcGIS 
  /// document opening/creating/closing events. Provides standarized startup and shutdown functionality. Provides
  /// access to Emgaats singleton objects such as Mediator and LayerLibrarian.
  /// </summary>  
  [ClassInterface(ClassInterfaceType.None)]  
  public class EmgaatsExtensionBase : ESRI.ArcGIS.Desktop.AddIns.Extension, IPersistVariant
  {
    private Mediator _mediator;
    private LayerLibrarian _librarian;
    /// <summary>
    /// Provides access to the current ArcGIS session
    /// </summary>
    protected IApplication _arcApp;
    private esriExtensionState _extensionState;

    /// <summary>
    /// Delegate for the ExtensionStateChanged event
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The EmgaatsExtensionArgs indicating which extension was added or removed</param>    
    public event ExtensionStateChangedHandler EmgaatsExtensionEnabledEvent;
    public event ExtensionStateChangedHandler EmgaatsExtensionDisabledEvent;    
    
    /// <summary>
    /// Raised when the ArcGIS session is shutting down
    /// </summary>
    public event EventHandler ShuttingDown;
    /// <summary>
    /// Occurs when an Emgaats Extension wishes to broadcast an information message to any subscribers
    /// </summary>
    public event MessageReportedEventHandler MessageReported;

    /// <summary>
    /// Called when a message is to be reported.
    /// </summary>
    /// <param name="e">The message to report</param>
    protected void OnMessageReported(MessageReportedArgs e)
    {
      if (MessageReported != null)
        MessageReported(this, e);
    }

    protected void ReportMessage(string message, ReportableMessageType type)
    {
      ReportableMessage rm = new ReportableMessage()
      {
        MessageType = type,
        Description = message
      };
      OnMessageReported(new MessageReportedArgs(rm));
    }

    /// <summary>
    /// Provides child classes with access to the Emgaats Mediator singleton
    /// </summary>
    protected Mediator Mediator
    {
      get
      {
        return _mediator;
      }
    }

    /// <summary>
    /// Provides child classes with access to the Emgaats LayerLibrarian singleton
    /// </summary>
    protected LayerLibrarian Librarian
    {
      get { return _librarian; }
    }
    
    protected override sealed void OnStartup()
    {
      base.OnStartup();

      Mediator.InitializeMediator();
      LayerLibrarian.InitializeLibrarian();     

      /*
      _arcApp = ArcMap.Application;

      if (_arcApp == null)
        return;

      SetUpDocumentEvent(_arcApp.Document);

      _mediator = Mediator.AttachToMediator(this);
      _librarian = LayerLibrarian.AttachToLibrarian(this);

      MessageQueue.AddMessenger(this);

      try
      {
        CustomStartup();
      }
      catch (Exception ex)
      {
        ReportMessage("Error starting extension: " + ex.Message, ReportableMessageType.Error);
      }*/
    }

    public void Shutdown()
    {
      if (ShuttingDown != null)
        ShuttingDown(this, EventArgs.Empty);
      
      _arcApp = null;
    }    

    #region IPersistVariant Members

    public virtual UID ID
    {
      get
      {
        UID typeID = new UIDClass();
        typeID.Value = GetType().GUID.ToString("B");
        return typeID;
      }
    }

    public virtual void Load(IVariantStream Stream)
    {
      //TODO: Load persisted data from document stream

      Marshal.ReleaseComObject(Stream);
    }

    public virtual void Save(IVariantStream Stream)
    {
      //TODO: Save extension related data to document stream

      Marshal.ReleaseComObject(Stream);
    }

    #endregion

    

  }

}
